<script src='http://shjs.sourceforge.net/lang/sh_javascript.js'></script>
<script src='http://shjs.sourceforge.net/sh_main.js'></script>
<link rel="stylesheet" href="../style/style.css">
<link rel='stylesheet' type='text/css' href='../style/code.css'>

<body onload="sh_highlightDocument('sh', 'javascript');">
<div id='supercontainer' ><title>
Using Anymote
</title>
<h1 id="exercise-6.-using-anymote">Exercise 6. Using Anymote</h1>
<h2 id="goal">Goal</h2>
<ul>
<li>Getting familiar with the different commands you can send to Google TV using Anymote</li>
</ul>
<p>We will be testing the Anymote buttons and trying different fling buttons. Pairing is done, an Anymote session has been started, the screen is green, and it's time to learn about using Anymote for communication.</p>
<center>
<img src="../images/using_anymote.png" width="90%" alt="Using Anymote" title="Using Anymote">
</center>

<h2 id="prep">Prep</h2>
<ul>
<li>Completed Exercise 1 <a href="install_extensions.html">Installing the AnymoteLearningExercise extension</a></li>
<li>Completed Exercise 2 <a href="initialize_gtvremote.html">Initializing the GTVRemote object</a></li>
<li>Completed Exercise 3 <a href="discovery.html">Discovery</a></li>
<li>Completed Exercise 4 <a href="pairing.html">Pairing</a></li>
<li>Completed Exercise 5 <a href="starting_anymote.html">Starting an Anymote session</a></li>
<li>Open the popup.js file in the text editor of your choice</li>
</ul>
<h2 id="anymote">Anymote</h2>
<p>The Anymote session has <a href="http://code.google.com/p/google-tv-chrome-extensions/wiki/AnymoteSession">six functions</a> related to communication, sendKeyEvent, sendMouseMove, sendMouseWheel, sendData, sendFling, and sendPing.</p>
<table><tbody><tr style="background-color: #ddd"><td style="border: 1px solid #ccc; padding: 5px;"> 
<strong>Returns</strong>
</td><td style="border: 1px solid #ccc; padding: 5px;"> 
<strong>Method</strong>
</td><td style="border: 1px solid #ccc; padding: 5px;"> 
<strong>Description</strong>
</td></tr> <tr><td style="border: 1px solid #ccc; padding: 5px;">  </td><td style="border: 1px solid #ccc; padding: 5px;"> 
sendKeyEvent(<i>keycode</i>, <i>action</i>)
</td><td style="border: 1px solid #ccc; padding: 5px;"> 
Sends a key event to the Google TV. <i>keycode</i> is a number that corresponds to an Anymote Keycode value. A complete list of values can be found in the Anymote protocol <a href="http://code.google.com/p/anymote-protocol/source/browse/proto/keycodes.proto" rel="nofollow">keycodes.proto file</a>. <i>action</i> is a number that tells Google TV if the key is coming up (0) or going down (1).
</td></tr> <tr><td style="border: 1px solid #ccc; padding: 5px;"> </td><td style="border: 1px solid #ccc; padding: 5px;"> 
sendMouseMove(<i>xDelta</i>, <i>yDelta</i>)
</td><td style="border: 1px solid #ccc; padding: 5px;"> 
Sends a mouse movement event. <i>xDelta</i> is a relative x-axis movement amount in pixels. <i>yDelta</i> is a relative y-axis movement amount in pixels.
</td></tr> <tr><td style="border: 1px solid #ccc; padding: 5px;"> </td><td style="border: 1px solid #ccc; padding: 5px;"> 
sendMouseWheel(<i>xScroll</i>, <i>yScroll</i>)
</td><td style="border: 1px solid #ccc; padding: 5px;"> 
Sends a mouse wheel event. <i>xScroll</i> is a relative x-axis scroll wheel amount in pixels. <i>yScroll</i> is a relative y-axis scroll wheel amount in pixels.
</td></tr> <tr><td style="border: 1px solid #ccc; padding: 5px;"> </td><td style="border: 1px solid #ccc; padding: 5px;"> 
sendData(<i>type</i>, <i>data</i>)
</td><td style="border: 1px solid #ccc; padding: 5px;"> 
Sends arbitrary string data to Google TV. <i>type</i> is a string. Valid types include 'com.google.tv.string', 'com.google.tv.intent', 'com.google.tv.url_update'. <i>data</i> is a string which is sent to the Google TV along with the type.
</td></tr> <tr><td style="border: 1px solid #ccc; padding: 5px;"> </td><td style="border: 1px solid #ccc; padding: 5px;"> 
sendFling(<i>uri</i>, <i>sequence</i>)
</td><td style="border: 1px solid #ccc; padding: 5px;"> 
Flings a URI to the Google TV. The uri is used to make an Android Intent which can be used to launch app Activities. <i>sequence</i> is an integer number greater 0. The Google TV will reply with a response that includes this sequence number to confirm the that intent was sent.
</td></tr> <tr><td style="border: 1px solid #ccc; padding: 5px;"> </td><td style="border: 1px solid #ccc; padding: 5px;"> 
sendPing()
</td><td style="border: 1px solid #ccc; padding: 5px;"> 
Sends a ping, which should result in an ack response.
</td></tr> </tbody></table>

<h2 id="send-key-event">Send key event</h2>
<p>The most basic, and perhaps most useful, function of Anymote is to send any button on a remote control. For example here we send the HOME and SEARCH keys.</p>
<center>
<img src="../images/send_key.png" width="60%" alt="Send Key" title="Send Key">
</center>

<p>This is done by using constants within googletvremote_constants.js. Find the on click event handlers within the popup.js file.</p>
<pre class="sh_javascript"><code>// 4. Using Anymote.
document.getElementById('home').addEventListener('click', function() {
  sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.HOME);
});
document.getElementById('search').addEventListener('click', function() {
  sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.SEARCH);
});
</code></pre>

<p>The sendAnymoteKeyEvent function is simply sending both the DOWN and then UP messages for the button. You can find the sendAnymoteKeyEvent function within the anymote_session_controller.js file.</p>
<pre class="sh_javascript"><code>var sendAnymoteKeyEvent = function(keycode) {
  anymoteSession.sendKeyEvent(keycode, googletvremote.anymote.Action.DOWN);
  anymoteSession.sendKeyEvent(keycode, googletvremote.anymote.Action.UP);
};
</code></pre>

<p>In addition to sending key events for button presses, you can also send key events on keyboard key presses. There is code within popup.js to send key events when certain keys are pressed on the keyboard.</p>
<pre class="sh_javascript"><code>document.body.addEventListener('keydown', function(e) {
    switch (e.keyCode) {
      case 13:  // Enter
        sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.DPAD_CENTER);
        break;
      case 37:  // Left arrow key
        sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.DPAD_LEFT);
        break;
      case 38:  // Up arrow key
        sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.DPAD_UP);
        break;
      case 39:  // Right arrow key
        sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.DPAD_RIGHT);
        break;
      case 40:  // Down arrow key
        sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.DPAD_DOWN);
        break;
    }
  });
</code></pre>

<p>Just for fun change a few key events. Maybe you could send a BACK command when someone hits 'b' (e.keyCode 66) on the keyboard. Or send MENU when someone hits 'm' (e.keyCode 77). There are many ways to do this more elegantly for a full keyboard, but this gives you the idea.</p>
BTW the solution to that challenge is this...
<pre class="sh_javascript"><code>document.body.addEventListener('keydown', function(e) {
    switch (e.keyCode) {
      // ... prior cases

      case 66:  // b key
        sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.BACK);
        break;
      case 77:  // m key
        sendAnymoteKeyEvent(googletvremote.anymote.KeyCode.MENU);
        break;
    }
  });
</code></pre>

<h2 id="mouse-events">Mouse events</h2>
<p>This exercise will not cover mouse events, but I assure you they are not hard to implement. The only caution I give is that all mouse events are relative movements, so be sure to send only relative movement values.</p>
<h2 id="send-data">Send data</h2>
<p>Send data is really a special command to the receiving application on the Google TV (called IP Remote) to carry out some action on your behalf. At present the only action (ie data type) is <i>com.google.tv.string</i>. This is a handy way to send a string instead of manually sending key DOWN and key UP events for each letter. In fact sendData is the recommended mechanism for sending generic keyboard keys instead of sending DOWN and UP commands for all keys and modifiers.</p>
<p>In the future more data actions will be added but <i>com.google.tv.string</i> is the only current data action. Try it out with the Hello World button. Just make sure there is an app open that will display keys before you hit the button.</p>
<center>
<img src="../images/send_string.png" width="55%" alt="Send String" title="Send String">
</center>

<p>Note, we send the SEARCH key before the string simply to give the String somewhere to display. You could just as easily open Chrome, or some other app the displays text, and send a string there instead. Search was just convenient. Who doesn't want to search for Hello World?</p>
<h2 id="send-an-android-intent-ie-fling-something">Send an Android Intent (ie Fling something)</h2>
<p>By far the coolest feature of Anymote is sendFling. I'm not really sure why we call it send fling instead of send Android Intent, but the word &quot;fling&quot; has stuck. Flinging lets you send any Intent you like to Google TV. One minor catch... you need to send the string representation of an Intent. For a simple data uri this is VERY easy. For a more complex intent it becomes very ugly to format the string to send complex Intents.</p>
<p>We'll try a few different tests within the Fling button. We'll send something, change the code, then send something different to see the results of different flings.</p>
<center>
<img src="../images/send_fling.png" width="45%" alt="Send Fling" title="Send Fling">
</center>


<h3 id="url-fling-to-open-chrome">1. Url fling to open Chrome</h3>
<p>Find the fling callback function within the popup.js file.</p>
<pre class="sh_javascript"><code>document.getElementById('uri-fling').addEventListener('click', function() {
  sendAnymoteFling('http://code.google.com/p/google-tv-chrome-extensions');
});
</code></pre>

Change it to fling a different page, pick any URL you like that is related to you. I'll fling our developers page.
<pre class="sh_javascript"><code>document.getElementById('uri-fling').addEventListener('click', function() {
  sendAnymoteFling('http://developers.google.com/tv/remote/');
});
</code></pre>

<p>This fling works by sending a simple Url. This URL is used as the data URI in an Intent. The intent has the default Action (ACTION_VIEW) and category. That particular Uri is recognized by the Chrome app, so Chrome launches on the Google TV with the Url.</p>
<p>One fun feature is to fling your current Chrome page. Using a chrome extension api you can get the current tab and fling that Url to the TV. Change the function, save popup.js, and reopen the popup window. Navigate anywhere on the web (away from the local instructions file), and fling that page to the TV.</p>
<pre class="sh_javascript"><code>document.getElementById('uri-fling').addEventListener('click', function() {
  chrome.tabs.getSelected(null, function(tab) {
    sendAnymoteFling(tab.url);
  });
});
</code></pre>

<p>Note, that it just copies the Url and won't transfer things like your login state.</p>
<h3 id="youtube-flings">2. YouTube flings</h3>
<p>There are a lot of apps on the Google TV beyond Chrome. Another popular app for flings is YouTube. Change the function to send a YouTube to the TV.</p>
<pre class="sh_javascript"><code>document.getElementById('uri-fling').addEventListener('click', function() {
  sendAnymoteFling('vnd.youtube://l3rmnD4PscY');
});
</code></pre>

<p>This scheme will open the YouTube app directly without asking for disambiguation. In addition to videos you can also fling things like YouTube channels and playlists.</p>
<pre class="sh_javascript"><code>document.getElementById('uri-fling').addEventListener('click', function() {
  sendAnymoteFling('vnd.youtube.channel://googletv');
  //sendAnymoteFling('vnd.youtube.channel://GoogleDevelopers');
});
</code></pre>


<h3 id="other-app-flings">3. Other app flings</h3>
<p>Beyond YouTube and Chrome there are still more apps pre-installed on Google TV. Here are a few more examples that launch other apps.</p>
<pre class="sh_javascript"><code>document.getElementById('uri-fling').addEventListener('click', function() {
    sendAnymoteFling('tv://');
});
</code></pre>

<p>Note that for the TV Player app there is also a LIVE_TV key event you could send, but I wanted to show the Intent version here.</p>
<p>Next change the fling to open the Google Play store. Go ahead and try this fling and install the Panoramio for Google TV app on your TV.</p>
<pre class="sh_javascript"><code>document.getElementById('uri-fling').addEventListener('click', function() {
  sendAnymoteFling('market://details?id=com.google.android.apps.panoramiogtv');
});
</code></pre>

<p>We'll use &quot;Panoramio for Google TV&quot; in the next step. So go ahead and install that app.</p>
<h3 id="advanced-flings">4. Advanced flings</h3>
<p>As mentioned earlier you can do more than just sending a data Uri with the default action (ACTION_VIEW) and category. You can send nearly any Intent via a string. This is particularly important for communicating with apps you've made that run on Google TV. For your own apps you know the package name and Activity class names. So you don't need to send a Uri with a scheme to figure out which Activity to launch, you can set the Intent component explicitly.</p>
<pre class="sh_javascript"><code>document.getElementById('uri-fling').addEventListener('click', function() {
  // Must install Panoramio for Google TV on your Google TV first.
  sendAnymoteFling('intent:#Intent;' +
      'component=com.google.android.apps.panoramiogtv/.ImageGrid;' +
      'end');  
});
</code></pre>

<p>This format looks intimidating at first, but really Android is just using a parseUri command on whatever string you send. Typically the parseUri command is called an Intent string that was made via the toUri command. However in a Chrome Extension we can't use these tools, but we can reverse engineer the Intent string and send nearly any Intent we'd like.</p>
<p>If you would like to use this feature read the <a href="https://code.google.com/p/google-tv-chrome-extensions/wiki/AdvancedFlings">Advanced Flings</a> wiki article.</p>
<h2 id="you-are-done">You are done</h2>
<p>You're done! Hopefully you feel comfortable using the Google TV NPAPI library for communication!</p>
<p>Feel free to look at &quot;What's next?&quot; to get ideas for using this library.</p>
<p><a href="../instructions.html">Back to main page</a> <span style="float: right;"><a href="next_steps.html">What's next?</a></span></p>
